home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
bixdos.arc
/
QUERY.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-11-24
|
10KB
|
306 lines
program Query;
{ This program allows variables in the COMMAND environment area to be
redefined interactivly. Its primary use is in .BAT files. Due to the
way COMMAND allocates the environment segment is isn't easy to
create new variables or increase the length of the value of old ones.
Therefore the variable to be set by query MUST be initialized to a string
of its largest legal size before executing QUERY.
Syntax:
QUERY [/R][/Y][/N][/U][/n1,n2] <varname> [<string>..[<string>]]
Example of Usage:
SET ANSWER=*
QUERY /Y ANSWER Do you want to delete all backup files?
IF %ANSWER%==Y GOTO DELETEM
GOTO EXIT
SET FILE=*************
QUERY FILE Enter the file name.ext:
Options:
/R Response is required
/Y Response must be either Y or N.
/N Response must be an integer
/<n1>[,<n2>] Response must be an integer range 1 ..<n1> or <n1>..<n2>
/U Convert response to upper case
}
type
EnvBuff = record
Env: array[1..2048] of char;
end;
EnvironmentPointer = ^EnvBuff;
Str4 = string[4];
str8 = string[8];
str9 = string[9];
str32 = string[32];
str64 = string[132];
var
EnvPtr,SearchPtr: EnvironmentPointer;
FirstChar, LastChar,
Index, VarLen, StringLen,
BufferLen, ParamIndex,Ival,
Source, Target, Count,
HighRange,LowRange,Col: integer;
Setname,VarName,Option: Str32;
NewVal: Str64;
EndOfEnv,Found,InOptions,
Yoption,Noption,Uoption,
Roption, RangeOption,
LegalResponse: boolean;
begin
If ParamCount > 0 then
begin
ParamIndex := 0;
InOptions := True;
Yoption := false;
Noption := false;
Uoption := false;
Roption := false;
RangeOption := false;
Repeat
begin
ParamIndex := ParamIndex + 1;
If ParamIndex > ParamCount then InOptions := False;
Option := ParamStr(ParamIndex);
If Option[1] = '/' then
begin
Index := 1;
While Index <= Length(Option) do
begin
If Option[Index] <> '/' then
Writeln('Error, options must be seperated by "/"s');
Index := Index + 1;
Case UpCase(Option[Index]) of
'/': ;
'Y': Yoption := true;
'N': Noption := true;
'U': Uoption := true;
'R': Roption := true;
'0'..'9': begin
RangeOption := true;
LowRange := 1;
HighRange := 0;
While ( (Option[Index] >= '0') and (Option[Index] <= '9') ) and
(Index <= Length(Option)) do
begin
HighRange := 10*HighRange + ( Ord(Option[Index])-Ord('0'));
Index := Index + 1;
end;
If Option[Index] = ',' then
begin
Index := Index + 1;
LowRange := HighRange;
HighRange := 0;
While ( (Option[Index] >= '0') and (Option[Index] <= '9') ) and
(Index <= Length(Option)) do
begin
HighRange := 10*HighRange + ( Ord(Option[Index])-Ord('0'));
Index := Index + 1;
end;
end;
If Index < Length(Option) then Index := Index - 1;
end {RangeOption};
Else Writeln('Invalid option:',Option[Index]);
end {Case};
Index := Index + 1;
end;
end
Else
InOptions := false;
end;
Until not InOptions;
{ Get the variable name from the parameter field and convert it to
upper case as COMMAND does. }
VarName := ParamStr(ParamIndex);
For Index := 1 to Length(VarName) do
VarName[Index] := UpCase(VarName[Index]);
{ Set up addressing so that the Env array is based in the segment the
command processor is using for variables. The command processor leaves a
pointer to a copy of the environment area in CS:2C }
MemW[ Seg(EnvPtr):Ofs(EnvPtr)+2 ] := MemW[Cseg:$002C];
MemW[ Seg(EnvPtr):Ofs(EnvPtr) ] := 0;
BufferLen := 0;
Repeat BufferLen := BufferLen + 1 Until EnvPtr^.Env[BufferLen] = #$01;
{ Search through memory for the REAL environment area. This will be
identical to the copy COMMAND provided us. This search is pretty quick
because command allocates program memory against its memory. }
Found := False;
SearchPtr := EnvPtr;
Repeat
begin
MemW[Seg(SearchPtr):Ofs(SearchPtr)+2] :=
MemW[Seg(SearchPtr):Ofs(SearchPtr)+2] - 1;
Col := 0;
Repeat Col := Col + 1;
Until (Col = BufferLen) or (EnvPtr^.Env[Col] <> SearchPtr^.Env[Col]);
If Col = BufferLen then Found := True;
end;
Until Found or (MemW[Seg(SearchPtr):Ofs(SearchPtr)+2] = $0000);
If Not Found then
begin
Writeln;
Writeln('COMMAND processor environment area not found in memory');
Halt;
end
Else
EnvPtr := SearchPtr;
With EnvPtr^ do
begin
Index := 1;
EndOfEnv := Env[1]=#$01;
EndOfEnv := False;
Found := False;
{ Scan the environment area for this variable name. Format expected here
is the variable name (in upper case) followed by an '=' then a
string terminated by and #$00 (ASCIIZ). Then end of environment is
indicated by a SOH (#$01) where variable name should begin. }
While not EndOfEnv and not Found do
begin
Setname := '';
While ( Env[Index] <> '=' ) and ( Env[Index] <> #$00 ) do
begin
Setname := Setname + Env[Index];
Index := Index + 1;
end;
If SetName = VarName then
Found := true
Else { skip this variables value }
Repeat Index := Index + 1 Until Env[Index] = #$00;
Index := Index + 1;
EndOfEnv := Env[Index] = #$01;
If EndOfEnv then
Writeln('Error:',Varname,' must be SET before using query');
end;
If Found then
begin
FirstChar := Index;
Repeat Index := Index + 1 Until Env[Index] = #$00;
LastChar := Index - 1;
StringLen := LastChar-FirstChar+1;
LegalResponse := false;
Repeat
begin
Index := ParamIndex+1;
While Index <= ParamCount do
begin
Write(ParamStr(Index),' ');
Index := Index + 1;
end;
Read(NewVal);
If Uoption or Yoption then For Col := 1 to Length(NewVal) do
NewVal[Col] := UpCase(NewVal[Col]);
LegalResponse := True;
If Yoption then
begin
If Length(NewVal) > 0 then NewVal := NewVal[1];
If ( NewVal <> 'N' ) and ( NewVal <> 'Y' ) then
begin
Writeln;
Writeln('Answer either "YES" or "NO"');
LegalResponse := False;
end;
end;
If Noption then
begin
Col := 1;
While Col <= Length(NewVal) do
If (NewVal[Col] > '9') or (NewVal[Col] < '0') then
begin
LegalResponse := False;
Col := Length(NewVal)+1;
Writeln;
Write('Response should be a number');
Writeln;
end
Else
Col := Col + 1;
end;
If Roption and (Length(NewVal) = 0) then
begin
LegalResponse := False;
Writeln;
Writeln('A response is required');
Writeln;
end;
If RangeOption then
begin
Ival := 0;
Col := 1;
While Col <= Length( NewVal ) do
begin
If ( Newval[Col] > '9' ) or ( NewVal[Col] < '0' ) then
begin
Col := Length( NewVal ) + 1;
Writeln;
Writeln('Response should be a number');
Writeln;
LegalResponse := False;
end
Else
begin
Ival := Ival*10 + ( Ord(NewVal[Col]) - Ord('0') );
Col := Col + 1;
end;
end;
If ( Ival > HighRange ) or ( Ival < LowRange ) then
begin
Writeln;
Writeln('Answer must be in the range ',LowRange,'..',
HighRange);
Writeln;
LegalResponse := False;
end;
end;
end;
Until LegalResponse;
{ Truncate the input string if it is too long }
If Length(NewVal) > StringLen then NewVal := Copy(NewVal,1,StringLen);
{ Now copy the new value to the environment area }
Col := 1;
Index := FirstChar;
While Col <= Length(NewVal) do
begin
Env[Index] := NewVal[Col];
Col := Col + 1;
Index := Index + 1;
end;
{ If the new value is shorter that the string length then shift the
rest of the environment area down }
Count := BufferLen - LastChar - 1;
Source := LastChar + 1;
Target := Index;
For Index := 1 to Count do
begin
Env[Target] := Env[Source];
Source := Source + 1;
Target := Target + 1;
end;
end;
end;
end;
end.